#!/usr/bin/env python
# coding: utf-8

import freeswitch
from rediscluster import client
import time
import random
import demjson


# 此运行在python2 上面，编码方面不太一样
    #成功版本，5版本加入呼出记录：LastCallInfo
###
# rdc.get_state()
# rdc.get_cop_num('20358')
# rdc.get_last_call_info('LastCallInfo:02023398853:13724059427')

class RedisClusterClient(object):
    instance = None
    city_show_num_pool_index_prix = "copShowNumIndex:"
    city_show_num_pool_list_prix = "copShowNumList:"

    def __init__(self, conn_list):
        self.conn_list = conn_list
        RedisClusterClient.instance = self.connect()

    def connect(self):
        """
        init connection
        :return: object
        """
        try:
            # 非密码连接redis集群
            # redisconn = StrictRedisCluster(startup_nodes=self.conn_list)
            # 使用密码连接redis集群
            redisconn = client.RedisCluster(startup_nodes=self.conn_list)
            return redisconn
        except Exception as e:
            print(e)
            return False

    def get_state(self):
        """
        :return:
        """
        res = RedisClusterClient(self.conn_list).connect()
        if not res:
            return False

        dic = res.cluster_info()

        for i in dic:
            ip = i.split(":")[0]
            if dic[i].get('cluster_state'):
                print("status, ip: ", ip, "value: ", dic[i].get('cluster_state'))

    def get_cop_show_num_dict(self, user_id):
        if user_id is None:
            return None
        key = "copShowNumMap:%s" % user_id
        return RedisClusterClient.instance.hgetall(name=key)

    def get_cop_num(self, user_id, city=None):

        b_show_num_dict = self.get_cop_show_num_dict(user_id)
        if b_show_num_dict is None:
            return None
        if city is None:
            """
            direct random one from own show number,if without city param
            """
            if len(b_show_num_dict) > 0:
                rl = list(b_show_num_dict.keys())
                return random.choice(rl)
        else:
            """
            random one from own show number,in a city showNum list
            """
            show_num_list = [x for x, y in b_show_num_dict.items() if y is city]
            if len(show_num_list) > 0:
                return random.choice(show_num_list)

        return None

    def get_cop_num_in_pool(self, city):
        """Take turns getting a display number in a city's number pool"""
        index_key = RedisClusterClient.city_show_num_pool_index_prix + city
        list_key = RedisClusterClient.city_show_num_pool_list_prix + city
        pool_size = RedisClusterClient.instance.llen(list_key)
        if pool_size is None or pool_size == 0:
            return None

        current_index = RedisClusterClient.instance.incr(index_key)

        if current_index >= pool_size:
            RedisClusterClient.instance.delete(index_key)

        show_num = RedisClusterClient.instance.lindex(list_key, current_index)
        if show_num is not None:
            return show_num

        return None

    def get_last_call_info(self, key):
        b_last_call_info_dict = RedisClusterClient.instance.hgetall(key)
        return b_last_call_info_dict


call_prix_dict = {
    '1': '98',
    '2': '97',
    '3': '96'
}
nodes = [
    {'host': '172.16.200.35', 'port': 6379},
    {'host': '172.16.200.36', 'port': 6379},
    {'host': '172.16.200.37', 'port': 6379},
    {'host': '172.16.200.38', 'port': 6379},
    {'host': '172.16.200.39', 'port': 6379},
    {'host': '172.16.200.40', 'port': 6379}
]

# init
rdc = RedisClusterClient(nodes)


def handler(session, args):  # args is string
    session.setAutoHangup(False)
    uuid = session.getVariable("uuid")

    if args is None:
        freeswitch.console_log("info", "call %s has no target call number in args param\n" % uuid)
        session.hangup("UNALLOCATED_NUMBER")
        return

    freeswitch.console_log("info", "call %s args string is: %s \n" % (uuid, args))

    X_uuid = session.getVariable("sip_h_X-uuid")
    X_create_user_id = session.getVariable("sip_h_X-create_user_id")
    X_city = session.getVariable("sip_h_X-city")

    if X_create_user_id is None or X_city is None or X_uuid is None:
        freeswitch.console_log("info", "X_uuid and X_create_user_id and X_uuid is required !")
        session.hangup("UNALLOCATED_NUMBER")
        return

    freeswitch.console_log("info", "city type str: %s \n" % isinstance(X_city, str))
    freeswitch.console_log("info", "X_create_user_id type str: %s \n" % isinstance(X_create_user_id, str))

    X_uuid = X_uuid.strip()
    X_create_user_id = X_create_user_id.strip()
    X_city = X_city.strip()

    freeswitch.consoleLog("info", "call %s extend params: X_uuid: %s, X_create_user_id: %s, X_city: %s \n" %
                          (uuid, X_uuid, X_create_user_id, X_city))
    try:
        # unicode
        # show_num = rdc.get_cop_num(X_create_user_id, X_city)

        # in city show_num pool mode
        show_num = rdc.get_cop_num_in_pool(X_city)

        # show_num_dict = rdc.get_cop_show_num_dict(X_create_user_id)
        # freeswitch.console_log("info", demjson.encode(show_num_dict, 'utf-8'))
        # show_num = "1002"
        if show_num is None:
            freeswitch.console_log("info", "get show_num from redis cluster is None,"
                                           "with user_id: %,city: % \n" % (X_create_user_id, X_city))
            session.hangup("UNALLOCATED_NUMBER")
            return

        show_num = show_num.encode('utf-8')
        freeswitch.console_log("err", "show_num: %s, type: %s \n" % (show_num, type(show_num)))

        session.setVariable("continue_on_fail", "false")
        session.setVariable("hangup_after_bridge", "true")
        session.setVariable("jitterbuffer_msec", "260:400:20")
        session.execute("export", "session_id=${uuid}")
        session.execute("export", "call_timeout=60")
        # TODO
        session.setHangupHook("myHangupHook", "test myHangupHook")
        # save record file
        today = time.strftime("%Y%m%d", time.localtime())

        record_save_base_paths = ["/cloudcall_file/rec_20050/freeswitchRecordFile/",
                                  "/cloudcall_file/rec_20051/freeswitchRecordFile/"]
        path = random.choice(record_save_base_paths) + today + "/" + uuid + ".wav"
        freeswitch.console_log("info", "choice path: %s" % path)
        session.execute("export", "nolocal:execute_on_answer=record_session " + path)

        call_prix = call_prix_dict[X_city]
        call_str = "{origination_caller_id_number=%s,origination_caller_id_name=%s}" \
                   "sofia/external/%s%s@10.41.46.57:5060" % (show_num, show_num, call_prix, args)
        freeswitch.console_log("info", "bridge string is: %s \n" % call_str)
        # session.execute("bridge", "user/%s" % args)
        session.execute("bridge", call_str)
        session.hangup()
    except Exception as err:
        freeswitch.console_log("err", "call %s exception,msg: %s \n" % (uuid, err))
        session.hangup("ORIGINATOR_CANCEL")


def myHangupHook(session, status, args):
    freeswitch.consoleLog("info", "myHangupHook: " + status + "\n")


if __name__ == '__main__':
    print(rdc.get_cop_num_in_pool('3'))

    print(rdc.get_cop_show_num_dict('20358'))

    # rdc.get_cop_num('20358')
    # rdc.get_last_call_info('LastCallInfo:02023398853:13724059427')
    # print("none city:"+rdc.get_cop_num('20358'))
    s1 = rdc.get_cop_num('20358', '2')
    # UTF-8 --> decode 解码 --> Unicode
    # Unicode --> encode 编码 --> GBK / UTF-8
    print("with city: %s" % s1)
    print("with city: %s" % type(s1))
    # a = 20358
    # b = 1
    # rdc.get_cop_num('20358')
    # rdc.get_last_call_info('LastCallInfo:02023398853:13724059427')
